#!/usr/bin/env python
# stoker_exec: Implementation of Stoker "exec" command
#
# Author:   Mike Murphy (mamurph@cs.clemson.edu)
# Revision: 26 February 2009
#
#   Copyright 2007-2009 Clemson University
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# This material is based upon work supported under a National Science
# Foundation Graduate Research Fellowship. Any opinions, findings,
# conclusions or recommendations expressed in this publication are those of
# the author(s) and do not necessarily reflect the views of the National
# Science Foundation.

import stoker_base

from stoker_defines import CFG_SSH, DFLT_SSH, CFG_SCP, DFLT_SCP

def run_remote_command(command, stdin_data):
   cmd = command.ssh
   args = [ command.target, command.command ]
   for arg in command.args:
      args.append(arg)
   return stoker_base.run_external(cmd, args, stdin_data)

def run_remote_script(command, script_stdin):
   code = 0
   out = ''
   err = ''
   filename = command.command
   cmd = command.ssh
   args = [ command.target, 'mktemp' ]
   code, name, err = stoker_base.run_external(cmd, args, '')
   name = name.strip()
   if code == 0:
      cmd = command.scp
      args = [ filename, command.target + ':' + name ]
      code, out, err = stoker_base.run_external(cmd, args, '')
      if code == 0:
         cmd = command.ssh
         args = [ command.target, 'chmod', '700', name ]
         code, out, err = stoker_base.run_external(cmd, args, '')
         if code == 0:
            cmd = command.ssh
            args = [ command.target, name ]
            for arg in command.args:
            	args.append(arg)
            code, out, err = stoker_base.run_external(cmd, args, script_stdin)
            cmd = command.ssh
            args = [ command.target, 'rm', '-f', name ]
            toss, throw, trash = stoker_base.run_external(cmd, args, '')
   return (code, out, err)

class ExecCommand(stoker_base.CommandObjectBase):
   def __init__(self, stoker_config, opts, args, target, extra):
      stoker_base.CommandObjectBase.__init__(self, stoker_config, opts, args, \
                                             target, extra)
      self.ssh = stoker_config.getParam(CFG_SSH, DFLT_SSH)
      self.scp = stoker_config.getParam(CFG_SCP, DFLT_SCP)
      self.script = False
      for opt, val in opts:
         if opt in ('--script', '-s'):
            self.script = True
      #
      self.command = self.args[0].strip()
      arglist = []
      for arg in self.args[1:]:
         arglist.append(arg.strip())
      self.args = arglist
   #
   def execute(self, stdin=''):
      if self.script:
         return run_remote_script(self, stdin)
      #
      return run_remote_command(self, stdin)
   #
